#include "stdafx.h"

#include <MyFC/LabelledWidget.h>
#include <MyFC/Utility.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

namespace My {

LabelledWidget::LabelledWidget()
{
	m_pWidget = 0;
	m_Layout = CaptionLeft;
	m_Alignment = ALIGN_HLEFT|ALIGN_VCENTER;
	m_TextRect = CRect(0, 0, 0, 0);
	m_Gap = 4;
}

void LabelledWidget::SetWidget(Widget * pWidget)
{
	if (pWidget != m_pWidget) {
		if (m_pWidget != 0)
			Remove(m_pWidget);
		m_pWidget = pWidget;
		if (m_pWidget != 0)
			Add(m_pWidget);
		LayoutControls();
	}
}

void LabelledWidget::SetCaption(const String & s)
{
	if (s != m_Caption) {
		m_Caption = s;
		LayoutControls();
	}
}

void LabelledWidget::SetLayout(Layout l)
{
	if (l != m_Layout) {
		m_Layout = l;
		LayoutControls();
	}
}

void LabelledWidget::SetAlignment(int a)
{
	if (a != m_Alignment) {
		m_Alignment = a;
		LayoutControls();
	}
}

void LabelledWidget::HandleFont()
{
	LayoutControls();
}

void LabelledWidget::SetGap(int value)
{
	m_Gap = value;
	UpdateBounds();
}

CSize LabelledWidget::GetPreferredSize() const
{
	My::ClientDC dc(const_cast<LabelledWidget *>(this));
	My::SaveObjects save(&dc);

	CSize sText = CSize(0, 0);
	if (!m_Caption.empty())
		sText = dc.GetTextExtent(m_Caption.c_str(), m_Caption.size());

	CSize sWidget(0, 0);
	if (m_pWidget != 0)
		sWidget = m_pWidget->GetPreferredSize();

	int gap = 0;
	if (!m_Caption.empty() && m_pWidget != 0)
		gap = m_Gap;

	CSize sAll(sWidget);
	sAll.cx += gap + sText.cx;
	if (sText.cy > sAll.cy)
		sAll.cy = sText.cy;

	return sAll;
}

void LabelledWidget::LayoutControls()
{
	My::ClientDC dc(this);
	My::SaveObjects save(&dc);

	CRect rClient = ClientRect();
	SelectFont(&dc);

	CSize sText = CSize(0, 0);
	if (!m_Caption.empty())
		sText = dc.GetTextExtent(m_Caption.c_str(), m_Caption.size());

	CSize sWidget(0, 0);
	if (m_pWidget != 0)
		sWidget = m_pWidget->GetPreferredSize();

	int gap = 0;
	if (!m_Caption.empty() && m_pWidget != 0)
		gap = m_Gap;

	CSize sAll(sWidget);
	sAll.cx += gap + sText.cx;
	if (sText.cy > sAll.cy)
		sAll.cy = sText.cy;

	CRect rAll(CPoint(0, 0), sAll);
	rAll = AlignRect(rClient, rAll, m_Alignment);
	rAll.IntersectRect(&rAll, &rClient);

	CRect rWidget(0, 0, 0, 0), rCaption(0, 0, 0, 0);
	rWidget.right = sWidget.cx;
	if (rAll.Width() < rWidget.right)
		rWidget.right = rAll.Width();
	rWidget.bottom = sWidget.cy;
	if (rAll.Height() < rWidget.bottom)
		rWidget.bottom = rAll.Height();

	rCaption.right = sText.cx;
	if (rAll.Width() - rWidget.Width() - gap < rCaption.right)
		rCaption.right = rAll.Width() - rWidget.Width() - gap;
	rCaption.bottom = sText.cy;
	if (rAll.Height() < rCaption.bottom)
		rCaption.bottom = rAll.Height();

	switch(m_Layout) {
	case CaptionLeft:
		rCaption = AlignRect(rAll, rCaption, ALIGN_HLEFT|ALIGN_VCENTER);
		rWidget = AlignRect(rAll, rWidget, ALIGN_HRIGHT|ALIGN_VCENTER);
		break;
	case CaptionRight:
		rCaption = AlignRect(rAll, rCaption, ALIGN_HRIGHT|ALIGN_VCENTER);
		rWidget = AlignRect(rAll, rWidget, ALIGN_HLEFT|ALIGN_VCENTER);
		break;
	}

	if (m_pWidget != 0)
		m_pWidget->SetBounds(rWidget);
	m_TextRect = rCaption;

	Invalidate();
}

void LabelledWidget::HandlePaint(CDC * pDC, const CRect & r)
{
	if (m_Caption.empty())
		return;

	//My::SaveObjects save(pDC);

	COLORREF OldTextColor;

	if (ControlEnabled(m_pWidget))
		OldTextColor = pDC->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
	else
		OldTextColor = pDC->SetTextColor(GetSysColor(COLOR_BTNSHADOW));

	int OldBkMode = pDC->SetBkMode(TRANSPARENT);

	pDC->DrawText(m_Caption.c_str(), &m_TextRect, DT_SINGLELINE|DT_LEFT|DT_VCENTER|DT_END_ELLIPSIS);

	pDC->SetBkMode(OldBkMode);
	pDC->SetTextColor(OldTextColor);
}

void LabelledWidget::HandleUpdateUI()
{
	Invalidate();
}


} // My
